﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Microsoft.Build.Framework;
using Microsoft.Build.Utilities;

namespace NotifiableLinqTests.MetaGenerator
{
	public class GenerateFixturesTask : AppDomainIsolatedTaskWraper
	{
		[Required]
		public ITaskItem[] Sources { get; set; }

		public string IntermediateOutputPath { get; set; }
		public string ProjectDir { get; set; }

		public override bool Execute()
		{
			// var generatedFileName = Path.Combine(Path.Combine(ProjectDir, IntermediateOutputPath), "tests.g.cs");
			var generatedFileName = Path.Combine(ProjectDir, "GeneratedTests.cs");
			using (var generator = new Generator())
			{
				File.WriteAllText(generatedFileName, generator.ToString());
			}
			// IncludeFileInBuild.Add(new TaskItem(generatedFileName));

			ReferenceFileInBuild.Add(new TaskItem(TargetFramework.Current.Assembly.Location));

			return true;
		}

		void WriteLog(string msg)
		{
			LogMessage("TestGen: " + msg);
		}

		//static readonly Regex _xmlAcceptanceRx = new Regex(@"(?i)\[TestClass\]\s*public\s+class\s+(?'ClassName'[a-z01-9_]+)\s*:\s*(?'BaseName'[a-z01-9_]+)", RegexOptions.Compiled | RegexOptions.ExplicitCapture | RegexOptions.CultureInvariant);

//		private void GenerateAcceptanceXmlStorageTests(ITaskItem item)
//		{
//			//LogLogMessage(MessageImportance.High, "\tFile: " + item.ItemSpec);
//
//			const string suffix = "_xml";
//
//			foreach(Match match in _xmlAcceptanceRx.Matches(File.ReadAllText(item.ItemSpec)))
//			{
//				// WriteLog("! " + match.Groups["ClassName"].Value);
//				var className = match.Groups["ClassName"].Value;
//				var baseClassName = match.Groups["BaseName"].Value;
//
//				if (className.EndsWith(suffix) || string.IsNullOrEmpty(baseClassName) || baseClassName == "FixtureMsTest")
//				{
//					continue;
//				}
//
//				_codeForHolder.AppendFormat(Resources.Pattern_XmlStorageAcceptance, className + suffix, className);
//			}
//		}

//		readonly StringBuilder _codeForHolder = new StringBuilder(Resources.HolderHeader);

//		static readonly Regex _tripleRx = new Regex(@"(?im)(#pragma\s+TestGen\s+(?'pragma'.*)$\s*)?\[TestClass\]\s*public class (?'ClassName'[a-z01-9_]+)\s*:\s*TripleTestsBase", RegexOptions.Compiled | RegexOptions.ExplicitCapture | RegexOptions.CultureInvariant);

//		static bool ItemAllowed(ITaskItem item)
//		{
//			return true;
//			// output file should be readable to aply several generation on each other (such as xmlStrorage after tripleTestBase)
//			// return Path.GetFileName(item.ItemSpec) != Path.GetFileName(OutputFile);
//		}

//		private void GenerateTripleFixtures(ITaskItem item)
//		{
//			var content = ReadFile(item.ItemSpec);
//			var matches = _tripleRx.Matches(content);
//
//			// LogLogMessage(MessageImportance.High, "# Matches for TripleFixtures: " + matches.Count);
//
//			foreach (Match match in matches)
//			{
//				// Log("! " + match.Groups["ClassName"].Value);
//				bool differentTransaction = true, differentContext = true, differentTransactionUndoRedo = true;
//
//				var pragma = match.Groups["pragma"].Value.Trim();
//				if(!string.IsNullOrEmpty(pragma))
//				{
//					WriteLog("PRAGMA: " + pragma + " in " + match.Groups["ClassName"].Value);
//					var pragmaParse = Regex.Match(pragma, @"(?'cmd'\w+)(\s(?'args'.*))?");
//					switch(pragmaParse.Groups["cmd"].Value.ToLowerInvariant())
//					{
//						case "ignore":
//							continue;
//						case "ignore_different_transaction":
//							differentTransaction = false;
//							break;
//						case "ignore_different_context":
//							differentContext = false;
//							break;
//						case "ignore_undoredo":
//						case "ignore_undo_redo":
//							differentTransactionUndoRedo = false;
//							break;
//						default:
//							throw new ApplicationException("UNKNOWN PRAGMA DIRRECTIVE: " + pragma);
//					}
//				}
//
//				// LogLogMessage(MessageImportance.High, "\tTestClass: " + match.Groups["ClassName"].Value);
//				var className = match.Groups["ClassName"].Value;
//				if(differentTransaction)
//				{
//					_codeForHolder.AppendFormat(Resources.TripleFixturePattern_transaction, className);
//				}
//				if(differentTransactionUndoRedo)
//				{
//					_codeForHolder.AppendFormat(Resources.TripleFixturePattern_UndoRedo, className);
//				}
//				if(differentContext)
//				{
//					_codeForHolder.AppendFormat(Resources.TripleFixturePattern_context, className);
//				}
//			}
//		}
//
//		private string ReadFile(string fileName)
//		{
//			if(Path.GetFileName(fileName) == Path.GetFileName(OutputFile))
//			{
//				return _codeForHolder.ToString();
//			}
//			return File.ReadAllText(fileName);
//		}
	}
}